#!/usr/bin/env python
# -*- coding: utf-8 -*-
# pycopux - Sequential copy of multiple files from different directories in one directory
# Jon Peeters - July 2011

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import gtk
import time
import os, sys, time, shutil
from threading import Thread

class EnterListener(Thread) :
	#def __init__(self) :
		#self.reset()

	def run (self) :
		while (True) :
			line = sys.stdin.readline()
			if (line.rstrip() == "") :
				self.finished = True
				return

	def reset(self) : 
		Thread.__init__(self)
		self.finished = False

	def isFinished (self) : 
		return self.finished

class Pycopy :
	DEST = "1. Destination "
	SRCS = "2. Sources "
	DESTWAITING = DEST + "(Un 'copier')"
	SRCSWAITING = SRCS + "(Un ou plusieurs 'copier' suivi de <enter>)"
	BASECOPYRESULTSFILE = "pycopy_resultats.txt"
	RSYNCMD = "rsync -a --progress"

	def __init__(self, cwd):
		self.clipboard = gtk.clipboard_get()		
		self.enterListener = EnterListener()
		self.cwd = cwd
		self.COPYRESULTSFILE = self.cwd + "/" + self.BASECOPYRESULTSFILE
		self.RSYNCMD += " 2>" + self.COPYRESULTSFILE

	def execute (self) :
		self.printMenu(self.DESTWAITING, "")	
		self.destination = self.waitForDestination()
		self.printMenu(self.DEST + " : " + self.destination, self.SRCSWAITING)
		strSources = self.waitForSources()
		self.sources = list(set(strSources.split('\n'))) # Remove duplicates				
		started = False
		while (not started) :
			self.printMenu(self.DEST + " : " + self.destination, self.SRCS + " :" + '\n'.join(self.sources))
			sys.stdout.write("\nDémarrer la copie ? [o] ")
			choice = sys.stdin.readline()
			choice = choice.rstrip()
			edit = (choice != "" and choice != "o" and choice != "O")
			started = (not edit)
			while (edit) :
				edit = self.modifySourceDestinations()			
		self.startCopy()
		os.system("clear")
		print("\n______________ Copie terminée avec succès ______________ \n")
		sys.stdin.readline()

	def modifySourceDestinations (self) :
		self.printMenu(self.DEST + " : " + self.destination, self.SRCS + " :" + '\n'.join(self.sources))
		sys.stdout.write("\nModifier 1 ou 2 (<enter> pour terminer) ? ")
		choice = sys.stdin.readline()
		choice = choice.rstrip()
		if (choice == "") : 
			return False
		if (choice == "2") :
			self.printMenu(self.DEST + " : " + self.destination, self.SRCSWAITING)
			strSources = self.waitForSources()
			self.sources = list(set(strSources.split('\n')))
		else :
			if (choice == "1") :
				self.printMenu(self.DESTWAITING, self.SRCS + " :" + '\n'.join(self.sources))	
				self.destination = self.waitForDestination()
		return True

	def printMenu (self, destinationTxt, sourcesTxt) : 
		os.system("clear")
		print(destinationTxt + "\n")
		print(sourcesTxt)

	def waitForDestination (self) :
		text = self.clipboard.wait_for_text()
		previous = text
		while (True) :
			if (text != previous and text != "") :
				return text
			time.sleep(1)
			text = self.clipboard.wait_for_text()

	def waitForSources (self) :
		self.enterListener.reset()
		self.enterListener.start()
		allSources = ""
		text = self.clipboard.wait_for_text()
		previous = text
		while (True) :
			if (text != previous and text != "") :
				allSources += "\n" + text
				previous = text
			if (self.enterListener.isFinished()) :
				return allSources
			time.sleep(1)
			text = self.clipboard.wait_for_text()

	def fatal_error(self, error) :
		os.system("clear")
		print("\n" + error + "\n")
		sys.exit(1)

	def startCopy(self) :
		for source in self.sources :
			if (source != "" and self.destination != "") : 			
				cmd = self.RSYNCMD + " '" + source + "' '" + self.destination + "'"				
				rc = os.system(cmd)
				if (rc != 0) :
					home = os.getenv("HOME")
					desktop =  home + "/Desktop"
					if (os.path.exists(home + "/Bureau")) :
						desktop = home + "/Bureau"
					tmp = desktop + "/" + self.BASECOPYRESULTSFILE
					if (os.path.exists(tmp)) :
						os.remove(tmp)
					shutil.move(self.COPYRESULTSFILE, desktop)
					self.fatal_error("Erreur lors de la copie.\n\nPlus d'information dans le fichier '" + self.BASECOPYRESULTSFILE + "', sur le bureau.")

if __name__== '__main__' :
	gtk.gdk.threads_init()

	pycopy = Pycopy(os.path.abspath(sys.path[0]))
	pycopy.execute()
